# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.shortcuts import redirect
from basic import models as basic_models
from django.db.models import Q, QuerySet
from django.core.paginator import Paginator
from basic.models import instance_info
import ast
from django.http import JsonResponse, HttpResponse
# Create your views here.
from django.forms.models import model_to_dict
import json
import cx_Oracle
import time
from django.utils import timezone
from django.utils.timezone import now
from django.contrib.auth.hashers import make_password
from django.contrib.auth.hashers import check_password
import pymysql

# logging
import logging
from django.http import HttpResponseRedirect

logger = logging.getLogger(__name__)

from django.shortcuts import render, redirect
import logging
from basic import models as basic_models  # 确保正确导入你的模型

logger = logging.getLogger(__name__)


class CustomUser:
    """ 自定义用户类，模拟 Django 的 User """

    def __init__(self, username):
        self.username = username
        self.is_authenticated = True  # 让 Django 认为用户已登录


def login(request):
    logger.info("Entry......")
    error_msg = ""

    if request.method == 'POST':
        logger.info("method: POST ...")
        username = request.POST.get('user', None)
        password = request.POST.get('pwd', None)

        logger.info("verifying account...")
        user_obj = basic_models.user_info.objects.filter(username=username).first()

        # if user_obj:
        # 校验密码
        if user_obj and check_password(password, user_obj.password):

            request.session['username'] = username
            request.session['is_login'] = True  # 手动标记已登录

            # **手动设置 request.user**
            request.user = CustomUser(username)

            # 记录 session
            request.session['last_activity'] = timezone.now().isoformat()

            logger.info(f"User {username} logged in successfully.")

            # 直接跳转
            # return redirect('/oratk_app/oratk_most_sessionevent')
            return redirect('/basic_app/app')

        else:
            error_msg = "用户名或密码错误"
            return render(request, 'basic_app/login.html', {'error_msg': error_msg})

    if request.method == 'GET':
        logger.info("method: GET ...")
        return render(request, 'basic_app/login.html', {'error_msg': error_msg})


##用户登出
def logout(request):
    logger.info("Entry......")
    if request.method == 'GET':
        ##请空session
        request.session.clear()
        return redirect('/basic_app/login.html')


##分页函数,传入三个参数：
# queryset结果集、当前页、每页显示的条目数
# 分页方法
def v_paginator(data, current_page_num, line_count_set):
    # 以下是分页
    # 5条一页
    # 总页数：paginator.num_pages
    # 当前页：current_page_num
    # 当前页数据：current_page
    # 总行数：paginator.count
    # 页数列表 paginator_num_pages_list
    global paginator
    global current_page
    global page_range
    global paginator_num_pages_list
    # paginator = Paginator(data, 5)  # 对所有数据进行分页
    paginator = Paginator(data, line_count_set)
    global last_page
    last_page = paginator.num_pages

    paginator_num_pages_list = [x for x in range(1, paginator.num_pages + 1)]
    # if paginator_num_pages_list==[]:
    #     paginator_num_pages_list = [1]
    try:  # 捕捉前台传过来的数据，传过来不正常的数据都跳到第一页
        global current_page
        current_page = paginator.page(current_page_num)  # 拿哪一页
        if paginator.num_pages > 11:  # 判断总页数是否大于 10 页
            if current_page_num - 5 < 1:  # 页数小于前5页就显示前10页
                current_range = range(1, 11)
                page_range = current_range
                return current_range, current_page, paginator, page_range, last_page, paginator_num_pages_list
            elif current_page_num + 5 > paginator.num_pages:  # 页数大于最后5页就显示最后10页
                current_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
                page_range = current_range
                return current_range, current_page, paginator, page_range, last_page, paginator_num_pages_list
            else:
                current_range = range(current_page_num - 4, current_page_num + 4)  # 其他范围为-5页到+5页
                page_range = current_range
                return current_range, current_page, paginator, page_range, last_page, paginator_num_pages_list
        else:
            page_range = paginator.page_range  # 小于10页就显示所有页数
            return page_range, current_page, paginator, page_range, last_page, paginator_num_pages_list

    except Exception as e:
        current_page_num = 1  # 随便乱传取第一页
        current_page = paginator.page(current_page_num)  # 随便乱传则取第一页
        current_range = range(1, 12)
        return paginator, current_page, current_range, page_range, last_page, paginator_num_pages_list


##获取数据库连接和数据库密码
def f_get_db_conn(id):
    logger.info("Entry......")
    global db_cx_conn
    global user_name
    global user_pwd
    global conn_string
    user_info = basic_models.instance_info.objects.filter(id=id).values('u_info', 'dba_role', 'conn_string').first()
    try:
        db_type = user_info['db_type']
    except Exception:
        logger.error("获取db类型失败")
        raise Exception('获取db类型失败')
    try:
        user_name = user_info['u_info'].split('/')[0]
        user_pwd = user_info['u_info'].split('/')[1]

    except Exception:
        logger.error("解析用户名密码失败,输入的用户密码格式可能不正确,正确格式如:liwk/abc")
        raise Exception('解析用户名密码失败。\n输入的用户密码格式可能不正确。\n正确格式如:liwk/abc')
    try:
        conn_string = user_info['conn_string']
    except Exception:
        logger.error("解析数据库连接串失败")
        raise Exception('解析数据库连接串失败')
    if user_name.upper() == 'SYS':
        logging.info(f'oracle_connect - {user_name}/***@{conn_string}')
        db_cx_conn = cx_Oracle.connect(user_name, user_pwd, conn_string, mode=cx_Oracle.SYSDBA)
    else:
        logging.info(f'oracle_connect - {user_name}/***@{conn_string}')
        db_cx_conn = cx_Oracle.connect(user_name, user_pwd, conn_string)
    return (db_cx_conn, user_name, user_pwd, conn_string, db_type)


##获取数据库连接和数据库密码
##根据id来建立连接或提供连接串，用户名密码来建立连接，如果都提供则id优先
def f_get_db_conn_2(id=None, user_info=None):
    logger.info("Entry......")
    # ✅ 只要传了 id，就以 id 为准，从数据库查
    if id is not None:
        user_info = basic_models.instance_info.objects.filter(id=id).values(
            'u_info', 'dba_role', 'conn_string', 'db_type'
        ).first()
        if not user_info:
            raise Exception(f"未找到 id={id} 的实例信息")
        logger.info(f"已根据 id={id} 获取连接信息")

    # 如果没传 id，才用 user_info
    elif user_info is not None:
        logger.info("未传 id，使用传入的 user_info 参数")
    else:
        logger.info('必须至少提供 id 或 user_info')
        raise Exception("必须至少提供 id 或 user_info")

    # 以下逻辑不变，统一使用 user_info
    try:
        db_type = user_info['db_type']
    except Exception:
        logger.error("获取db类型失败")
        raise Exception('获取db类型失败')

    try:
        user_name = user_info['u_info'].split('/')[0]
        user_pwd = user_info['u_info'].split('/')[1]
    except Exception:
        logger.error("解析用户名密码失败，格式应为 user/pass")
        raise Exception('解析用户名密码失败，格式应为 user/pass')

    try:
        conn_string = user_info['conn_string']
    except Exception:
        logger.error("解析数据库连接串失败")
        raise Exception('解析数据库连接串失败')


    try:
    ##oracle 连接
        if db_type == 'ORACLE':
            active_check_sql = 'select 1 from dual'
            if user_name.upper() == 'SYS':
                logger.info(f'oracle_connect - {user_name}/***@{conn_string}')
                db_conn = cx_Oracle.connect(user_name, user_pwd, conn_string, mode=cx_Oracle.SYSDBA)
            else:
                logger.info(f'oracle_connect - {user_name}/***@{conn_string}')
                db_conn = cx_Oracle.connect(user_name, user_pwd, conn_string)

        ## mysql 连接
        elif db_type == 'MYSQL':
            active_check_sql = 'select 1'
            try:
                host, port = conn_string.split(':')
                port = int(port)
            except Exception:
                raise Exception("MySQL 连接串格式应为 host:port")
            db_conn = pymysql.connect(host=host, port=port, user=user_name, passwd=user_pwd)


        else:
            raise Exception(f"暂不支持的数据库类型: {db_type}")
        return db_conn, user_name, user_pwd, conn_string, db_type, active_check_sql
    except Exception as e:
        logger.error(e)
        raise Exception(e)



##数据库探活
def db_check(id=None, user_info=None):
    curr_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    db_conn = conn_cursor = None

    result = {
        "ins_active": "FAILED",
        "ins_active_msg": "FAILED",
        "db_type": "UNKNOWN",
        "db_version": "UNKNOWN",
        "ins_get_version_msg": "最后一次探活失败，未更新版本号",
        "ins_active_time": curr_time_str
    }

    version_fetched = False

    try:
        if id is not None:
            db_conn, user_name, user_pwd, conn_string, db_type, active_check_sql = f_get_db_conn_2(id=id)
            result["db_type"] = db_type
        elif user_info is not None:
            db_conn, user_name, user_pwd, conn_string, db_type, active_check_sql = f_get_db_conn_2(user_info=user_info)
            result["db_type"] = db_type
        else:
            raise ValueError("id 和 user_info 不能同时为 None")

        conn_cursor = db_conn.cursor()

        try:
            conn_cursor.execute(active_check_sql)
            # print(conn_cursor.fetchone())
            result["ins_active"] = "SUCCESS"
            result["ins_active_msg"] = "SUCCESS"
        except Exception as e:
            result["ins_active"] = "FAILED"
            result["ins_active_msg"] = str(e)
            result["ins_get_version_msg"] = "最后一次探活失败，未更新版本号"

        if result["ins_active"] == "SUCCESS":
            try:
                version_sql_map = {
                    "ORACLE": "SELECT version FROM v$instance",
                    "MYSQL": "SELECT VERSION()"
                }
                db_version_sql = version_sql_map.get(result["db_type"].upper())
                if db_version_sql:
                    conn_cursor.execute(db_version_sql)
                    result["db_version"] = conn_cursor.fetchone()[0]
                    result["ins_get_version_msg"] = ""
                    version_fetched = True
                else:
                    result["ins_get_version_msg"] = f"不支持的数据库类型: {result['db_type']}"
            except Exception as e:
                result["ins_get_version_msg"] = str(e)
    except Exception as e:
        result["ins_active"] = "FAILED"
        result["ins_active_msg"] = str(e)
        result["ins_get_version_msg"] = "最后一次探活失败，未更新版本号"
    finally:
        if conn_cursor:
            conn_cursor.close()
        if db_conn:
            db_conn.close()

    if id is not None:
        update_fields = {
            "ins_active": result["ins_active"],
            "ins_active_msg": result["ins_active_msg"],
            "ins_active_time": result["ins_active_time"],
            "ins_get_version_msg": result["ins_get_version_msg"],
        }
        if version_fetched:
            update_fields["db_version"] = result["db_version"]

        basic_models.instance_info.objects.filter(id=id).update(**update_fields)
        return result
    else:
        return result

###dashboard
def dashboard(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.session.get('is_login', None):
        ##关闭浏览器删除session
        request.session.set_expiry(0)
        ins_active_info = []
        ins_inactive_info = []
        ins_locked_info = []
        ins_total_info = []
        ins_oracle_locked = basic_models.instance_info.objects.filter(status='LOCKED', db_type='ORACLE').count()
        ins_mysql_locked = basic_models.instance_info.objects.filter(status='LOCKED', db_type='MYSQL').count()
        ins_other_locked = basic_models.instance_info.objects.filter(status='LOCKED').exclude(db_type='MYSQL').exclude(
            db_type='ORACLE').count()

        ins_oracle_failed = basic_models.instance_info.objects.filter(ins_active='FAILED', db_type='ORACLE').count()
        ins_mysql_failed = basic_models.instance_info.objects.filter(ins_active='FAILED', db_type='MYSQL').count()
        ins_other_failed = basic_models.instance_info.objects.filter(ins_active='FAILED').exclude(
            db_type='MYSQL').exclude(
            db_type='ORACLE').count()

        ins_oracle_success = basic_models.instance_info.objects.filter(ins_active='SUCCESS', db_type='ORACLE').count()
        ins_mysql_success = basic_models.instance_info.objects.filter(ins_active='SUCCESS', db_type='MYSQL').count()
        ins_other_success = basic_models.instance_info.objects.filter(ins_active='SUCCESS').exclude(
            db_type='MYSQL').exclude(db_type='ORACLE').count()

        ins_total_oracle = basic_models.instance_info.objects.filter(db_type='ORACLE').count()
        ins_total_mysql = basic_models.instance_info.objects.filter(db_type='MYSQL').count()
        ins_total_other = basic_models.instance_info.objects.filter().exclude(db_type='MYSQL').exclude(
            db_type='ORACLE').count()

        ins_active_info.append(ins_oracle_success)
        ins_active_info.append(ins_mysql_success)
        ins_active_info.append(ins_other_success)
        ins_inactive_info.append(ins_oracle_failed)
        ins_inactive_info.append(ins_mysql_failed)
        ins_inactive_info.append(ins_other_failed)
        ins_locked_info.append(ins_oracle_locked)
        ins_locked_info.append(ins_mysql_locked)
        ins_locked_info.append(ins_other_locked)
        ins_total_info.append(ins_total_oracle)
        ins_total_info.append(ins_total_mysql)
        ins_total_info.append(ins_total_other)
        return render(request, 'basic_app/dashboard.html',
                      {'ins_active_info': ins_active_info, 'ins_inactive_info': ins_inactive_info,
                       'ins_locked_info': ins_locked_info, 'ins_total_info': ins_total_info})
    else:
        return redirect('/basic_app/login.html')


#####uesr展示页+搜索
def user(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        # v_paginator 为分页函数
        # 参数为：
        # userinfo_result： queryset 结果集
        # currentpage_num:当前选着的页数,默认为1
        # line_count_set：每页显示的条目数,默认为5
        currentpage_num = int(request.GET.get('page', '1'))
        line_count_set = int(request.GET.get('line_count', 5))
        user_search = request.GET.get('user_search', '')

        userinfo_result = basic_models.user_info.objects.filter(Q(email__contains=user_search)
                                                                | Q(username__contains=user_search)
                                                                | Q(iphone__contains=user_search)
                                                                | Q(status__contains=user_search))
        v_paginator(userinfo_result, currentpage_num, line_count_set)

        return render(request, 'basic_app/user.html',
                      {'current_page': current_page, 'paginator': paginator, 'line_count': line_count_set,
                       'page_range': page_range, 'last_page': last_page, 'current_page_num': currentpage_num,
                       'paginator_num_pages_list': paginator_num_pages_list
                          , 'search': user_search})
        # return render(request, 'basic_app/user.html',locals())


##用户—添加
def user_add_edit(request):
    logger.info("Entry......")
    if request.method == 'POST':
        edit_id = request.POST.get('add_id', '')
        add_user = request.POST.get('add_user', None)
        add_pwd = request.POST.get('add_pwd', None)
        add_email = request.POST.get('add_email', None)
        add_phone = request.POST.get('add_phone', None)
        add_dept = request.POST.get('add_dept', None)
        add_status = request.POST.get('add_status', None)
        password_hash = make_password(add_pwd)
        if len(edit_id) > 0:
            basic_models.user_info.objects.filter(id=edit_id).update(username=add_user, password=password_hash,
                                                                     email=add_email,
                                                                     iphone=add_phone
                                                                     , status=add_status, dept=add_dept)
        else:
            basic_models.user_info.objects.create(username=add_user, password=password_hash, email=add_email,
                                                  iphone=add_phone
                                                  , dept=add_dept, status=add_status)
        return redirect("/basic_app/user")

    if request.method == 'GET':
        nid = request.GET.get('nid')
        edit_result = basic_models.user_info.objects.filter(id=nid)
        userinfo_result = {}
        for val in edit_result:
            val = model_to_dict(val)
            userinfo_result = dict(userinfo_result, **(val))
        return HttpResponse(json.dumps(userinfo_result), content_type='application/json')


##用户删除
def user_delete(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        nid = request.GET.get('nid')
        basic_models.user_info.objects.filter(id=nid).delete()
        return redirect("/basic_app/user")


##用户锁定
def user_lock(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        nid = request.GET.get('nid')
        basic_models.user_info.objects.filter(id=nid).update(status='LOCKED')
        return redirect("/basic_app/user")


##用户信息详情
def user_more(request):
    logger.info("Entry......")
    if request.method == 'POST':
        return redirect("/basic_app/user")
    if request.method == 'GET':
        nid = request.GET.get('nid')
        more_result = basic_models.user_info.objects.get(id=nid)
        return render(request, 'basic_app/user_more.html', {'more_result': more_result})


##实例展示页
def instance(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        # v_paginator 为分页函数
        # 参数为：
        # userinfo_result： queryset 结果集
        # currentpage_num:当前选着的页数,默认为1
        # line_count_set：每页显示的条目数,默认为5
        currentpage_num = int(request.GET.get('page', '1'))
        line_count_set = int(request.GET.get('line_count', 5))
        user_search = request.GET.get('user_search', '')
        ins_status = request.GET.get('ins_status', 'VALID')
        ins_type = request.GET.get('ins_type', 'ALL')
        if ins_status == 'ALL':
            ins_stats_list = ['VALID', 'LOCKED']
        else:
            ins_stats_list = [ins_status]
        if ins_type == 'ALL':
            ins_type_list = ['ORACLE', 'MYSQL', 'MONGO', 'REDIS', 'POSTGRESQL']
        else:
            ins_type_list = [ins_type]
        instanceinfo_result = basic_models.instance_info.objects.filter(Q(dbname__contains=user_search)
                                                                        | Q(ip__contains=user_search)
                                                                        | Q(port__contains=user_search)
                                                                        | Q(conn_string__contains=user_search)
                                                                        | Q(sid__contains=user_search)
                                                                        | Q(status__contains=user_search)
                                                                        | Q(db_type__contains=user_search)
                                                                        | Q(db_version__contains=user_search)
                                                                        | Q(remark__contains=user_search)
                                                                        | Q(ins_active__contains=user_search),
                                                                        status__in=ins_stats_list,
                                                                        db_type__in=ins_type_list
                                                                        ).order_by('id')
        v_paginator(instanceinfo_result, currentpage_num, line_count_set)

        return render(request, 'basic_app/instance.html',
                      {'current_page': current_page, 'paginator': paginator, 'line_count': line_count_set,
                       'page_range': page_range, 'last_page': last_page, 'current_page_num': currentpage_num,
                       'paginator_num_pages_list': paginator_num_pages_list
                          , 'search': user_search, 'ins_status': ins_status, 'ins_type': ins_type})


##实例添加或编辑
def instance_add_edit(request):
    logger.info("Entry......")
    if request.method == 'POST':
        try:
            ##搜索和分页信息
            line_count_set = request.POST.get('line_count_set', None)
            page_set = request.POST.get('page_set', None)
            search = request.POST.get('search', None)
            ##要新增或更改的信息
            edit_id = request.POST.get('add_id', '')
            add_dbname = request.POST.get('add_dbname', None)
            add_ip = request.POST.get('add_ip', None)
            add_port = request.POST.get('add_port', None)
            add_sid = request.POST.get('add_sid', None)
            add_conn_string = request.POST.get('add_conn_string', None)
            add_user_pwd = request.POST.get('add_user_pwd', None)
            add_sysdba_role = request.POST.get('add_sysdba_role', None)
            add_remark = request.POST.get('add_remark', None)
            add_type = request.POST.get('add_type', None)
            add_status = request.POST.get('add_status', None)
            add_service_name = request.POST.get('add_service_name', None)

            if len(edit_id) > 0:
                path = '/basic_app/instance' + '?page=%s&line_count=%s&user_search=%s' % (
                    page_set, line_count_set, search)
                basic_models.instance_info.objects.filter(id=edit_id).update(dbname=add_dbname, ip=add_ip,
                                                                             port=add_port,
                                                                             sid=add_sid, conn_string=add_conn_string,
                                                                             service_name=add_service_name,
                                                                             remark=add_remark, db_type=add_type,
                                                                             status=add_status, u_info=add_user_pwd,
                                                                             dba_role=add_sysdba_role)

                # 单次探活
                db_check(id=edit_id)
                return HttpResponse(path)
            else:
                user_info = {
                    "u_info": add_user_pwd,
                    "conn_string": add_conn_string,
                    "db_type": add_type
                }
                # ins_active, ins_active_msg, db_version,curr_time_str = db_check(user_info=user_info)
                ins_active, ins_active_msg, db_type, db_version, curr_time_str = db_check(user_info=user_info)

                basic_models.instance_info.objects.create(dbname=add_dbname, ip=add_ip, port=add_port,
                                                          sid=add_sid, conn_string=add_conn_string,
                                                          service_name=add_service_name,
                                                          remark=add_remark, db_type=add_type, status=add_status,
                                                          u_info=add_user_pwd, dba_role=add_sysdba_role,
                                                          ins_active=ins_active,
                                                          ins_active_msg=ins_active_msg,
                                                          ins_active_time=curr_time_str,
                                                          db_version=db_version)

                return HttpResponse("/basic_app/instance")
        except Exception as err:
            return HttpResponse("AJAX_ERR:  %s " % (err))

    if request.method == 'GET':
        nid = request.GET.get('nid')
        edit_result = basic_models.instance_info.objects.filter(id=nid)
        instanceinfo_result = {}
        for val in edit_result:
            val = model_to_dict(val)
            instanceinfo_result = dict(instanceinfo_result, **(val))
        return HttpResponse(json.dumps(instanceinfo_result), content_type='application/json')


##实例——删除
def instance_delete(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        nid = request.GET.get('nid')
        basic_models.instance_info.objects.filter(id=nid).delete()
        return redirect("/basic_app/instance")


##实例——锁定
def instance_lock(request):
    logger.info("Entry......")
    if request.method == 'POST':
        ##搜索和分页信息
        try:
            nid = request.POST.get('nid', None)
            basic_models.instance_info.objects.filter(id=nid).update(status='LOCKED')
            return HttpResponse('SUCCESS')
        except Exception as e:
            return HttpResponse(e)
    if request.method == 'GET':
        pass
        # if request.session.get('is_login',None):
        #     ##关闭浏览器删除session
        #     request.session.set_expiry(0)
        #     nid = request.GET.get('nid')
        #     models.instance_info.objects.filter(id=nid).update(status='LOCKED')
        #     return redirect("/basic_app/instance")
        # else:
        #     return redirect('/basic_app/login.html')


##实例信息详情
def instance_more(request):
    logger.info("Entry......")
    if request.method == 'POST':
        return redirect("/basic_app/instance")
    if request.method == 'GET':
        nid = request.GET.get('nid')
        more_result = basic_models.instance_info.objects.get(id=nid)
        return render(request, 'basic_app/instance_more.html', {'more_result': more_result})

from collections import defaultdict

def instance_ins_check(request):
    logger.info("Entry......")
    curr_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    if request.method == 'POST':
        return redirect("/basic_app/instance")
    if request.method == 'GET':
        ##批量探活
        nid = request.GET.get('nid', None)

        if not nid:
            db_type = request.GET.get('db_type')
            db_status = request.GET.get('db_status')
            if db_type == 'ALL':
                db_types = ['ORACLE', 'MYSQL', 'POSTGRESQL', 'MONGODB','REDIS']
            else:
                db_types = [db_type]
            # 如果nid为none #一次探活
            # 获取全部实例，循环
            ins_info = basic_models.instance_info.objects.filter(db_type__in=db_types, status=db_status).values('id','conn_string','db_type')
            stats = defaultdict(lambda: {"success": 0, "failed": 0, "total": 0})
            for ins in ins_info:
                db_type = ins['db_type']
                f_result = db_check(id=ins['id'])
                # 更新该数据库类型统计e'
                stats[db_type]["total"] += 1
                # 更新汇总统计
                stats["all"]["total"] += 1
                if f_result['ins_active'] == 'SUCCESS':
                    stats[db_type]["success"] += 1
                    stats["all"]["success"] += 1
                else:
                    stats[db_type]["failed"] += 1
                    stats["all"]["failed"] += 1
            # json_info = {'ins_check_type': 'all', 'total_c': total_count, 'success_c': success_count,
            #              'failed_c': failed_count, 'url': '/basic_app/instance'}
            logger.info('统计结果:'+ str(dict(stats)))
            return JsonResponse(dict(stats))
            #return JsonResponse(json_info)
        else:
            line_count_set = request.GET.get('line_count_set', None)
            page_set = request.GET.get('page_set', None)
            search = request.GET.get('search', None)
            # 单次探活
            db_check(nid)
            path = '/basic_app/instance' + '?page=%s&line_count=%s&user_search=%s' % (page_set, line_count_set, search)
            json_info = {'ins_check_type': 'one', 'url': path}
            return JsonResponse(json_info)


##主机展示
def host(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        currentpage_num = int(request.GET.get('page', '1'))
        line_count_set = int(request.GET.get('line_count', 5))
        user_search = request.GET.get('user_search', '')

        hostinfo_result = basic_models.host_info.objects.filter(Q(name__contains=user_search)
                                                                | Q(hostname__contains=user_search)
                                                                | Q(ip__contains=user_search)
                                                                | Q(gm_ip__contains=user_search)
                                                                | Q(other_ip__contains=user_search)
                                                                | Q(status__contains=user_search)
                                                                | Q(type__contains=user_search)
                                                                | Q(remark__contains=user_search)
                                                                | Q(place__contains=user_search)
                                                                )
        v_paginator(hostinfo_result, currentpage_num, line_count_set)
        return render(request, 'basic_app/host.html',
                      {'current_page': current_page, 'paginator': paginator, 'line_count': line_count_set,
                       'page_range': page_range, 'current_page_num': currentpage_num,
                       'paginator_num_pages_list': paginator_num_pages_list
                          , 'search': user_search})


##主机添加、修改
def host_add_edit(request):
    logger.info("Entry......")
    if request.method == 'POST':
        try:
            ##搜索和分页信息
            line_count_set = request.POST.get('line_count_set', None)
            page_set = request.POST.get('page_set', None)
            search = request.POST.get('search', None)
            ##要新增或更改的信息
            edit_id = request.POST.get('add_id', '')
            add_name = request.POST.get('add_name', None)
            add_hostname = request.POST.get('add_hostname', None)
            add_desc = request.POST.get('add_desc', None)
            add_ip = request.POST.get('add_ip', None)
            add_port = request.POST.get('add_port', None)
            add_gm_ip = request.POST.get('add_gm_ip', None)
            add_other_ip = request.POST.get('add_other_ip', None)
            add_status = request.POST.get('add_status', None)
            add_type = request.POST.get('add_type', None)
            add_osversion = request.POST.get('add_osversion', None)
            add_remark = request.POST.get('add_remark', None)
            add_place = request.POST.get('add_place', None)

            # 判断编辑还是新增
            if len(edit_id) > 0:
                path = '/basic_app/host' + '?page=%s&line_count=%s&user_search=%s' % (page_set, line_count_set, search)
                basic_models.host_info.objects.filter(id=edit_id).update(name=add_name, hostname=add_hostname,
                                                                         desc=add_desc, ip=add_ip,
                                                                         port=add_port, gm_ip=add_gm_ip,
                                                                         other_ip=add_other_ip, status=add_status,
                                                                         type=add_type,
                                                                         osversion=add_osversion,
                                                                         remark=add_remark, place=add_place)
                return HttpResponse(path)

            else:
                basic_models.host_info.objects.create(name=add_name, hostname=add_hostname, desc=add_desc, ip=add_ip,
                                                      port=add_port, gm_ip=add_gm_ip,
                                                      other_ip=add_other_ip, status=add_status, type=add_type,
                                                      osversion=add_osversion,
                                                      remark=add_remark, place=add_place)
                return HttpResponse("/basic_app/host")
        except Exception as err:
            return HttpResponse("AJAX_ERR:  %s " % (err))

    if request.method == 'GET':
        if request.session.get('is_login', None):
            request.session.set_expiry(0)
            nid = request.GET.get('nid')
            edit_result = basic_models.host_info.objects.filter(id=nid)
            hostinfo_result = {}
            for val in edit_result:
                val = model_to_dict(val)
                hostinfo_result = dict(hostinfo_result, **(val))
            return HttpResponse(json.dumps(hostinfo_result), content_type='application/json')
        else:
            return redirect('/basic_app/login.html')


def host_delete(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        nid = request.GET.get('nid')
        basic_models.host_info.objects.filter(id=nid).delete()
        return redirect("/basic_app/host")


##主机锁定
def host_lock(request):
    logger.info("Entry......")
    if request.method == 'POST':
        pass
    if request.method == 'GET':
        nid = request.GET.get('nid')
        basic_models.host_info.objects.filter(id=nid).update(status='停用')
        return redirect("/basic_app/host")


##主机详情
def host_more(request):
    logger.info("Entry......")
    if request.method == 'POST':
        return redirect("/basic_app/host")
    if request.method == 'GET':
        nid = request.GET.get('nid')
        more_result = basic_models.host_info.objects.get(id=nid)
        return render(request, 'basic_app/host_more.html', {'more_result': more_result})


##APP-展示页
def app(request):
    logger.info("Entry......")
    if request.method == 'POST':
        print(2)
        pass
    if request.method == 'GET':
        print(1)
        currentpage_num = int(request.GET.get('page', '1'))
        line_count_set = int(request.GET.get('line_count', 5))
        user_search = request.GET.get('user_search', '')

        appinfo_result = basic_models.app_info.objects.filter(Q(app_name__contains=user_search)
                                                              | Q(app_addr__contains=user_search)
                                                              | Q(app_desc__contains=user_search)
                                                              | Q(img_addr__contains=user_search)
                                                              | Q(source__contains=user_search)
                                                              | Q(target__contains=user_search)
                                                              ).order_by('id')
        apps = basic_models.app_info.objects.all().order_by('id')
        v_paginator(appinfo_result, currentpage_num, line_count_set)

        return render(request, 'basic_app/app.html',
                      {'current_page': current_page, 'paginator': paginator, 'line_count': line_count_set,
                       'page_range': page_range, 'current_page_num': currentpage_num,
                       'paginator_num_pages_list': paginator_num_pages_list, 'apps': apps
                          , 'search': user_search})


import os


def add_app(request):
    logger.info("Entry......")
    if request.method == 'POST':
        try:
            app_name = request.POST.get('add_app_name', None)
            app_desc = request.POST.get('add_app_desc', None)
            app_addr = request.POST.get('add_app_addr', None)
            img_file = request.FILES.get('add_img_addr', None)
            app_source = request.POST.get('add_app_source', None)
            app_target = request.POST.get('add_app_target')

            if img_file:
                img_addr = img_file.name
                # 获取文件的内容
                file_content = img_file.read()
                # 获取当前视图函数所在文件的路径
                current_file_path = os.path.abspath(__file__)  #
                # 获取上两级目录路径
                parent_dir = os.path.dirname(current_file_path)  # 当前文件的父目录
                grandparent_dir = os.path.dirname(parent_dir)  # 当前文件父目录的父目录
                # 拼接 templates/ora_dir 的路径
                img_path = os.path.join(grandparent_dir, 'static', 'img', img_file.name)

                # 保存文件
                with open(img_path, 'wb') as f:
                    for chunk in img_file.chunks():
                        f.write(chunk)
            else:
                img_addr = 'span.png'
                # 记录到表
            basic_models.app_info.objects.create(app_name=app_name, app_desc=app_desc, app_addr=app_addr,
                                                 img_addr=img_addr, source=app_source, target=app_target)
            return JsonResponse({'status': 'success', 'file_path': img_addr})

        except Exception as e:
            return JsonResponse({'status': 'faild', 'file_path': e})


def app_delete(request):
    logger.info("Entry......")
    if request.method == 'GET':
        try:
            id = request.GET.get('nid')
            basic_models.app_info.objects.filter(id=id).delete()
            return redirect("/basic_app/app")
        except Exception as e:
            return HttpResponse('出错啦：' + str(e))
